package com.lordtan.persistance.dao.impl;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.lordtan.commom.utils.JpqlUtils;
import com.lordtan.persistance.dao.IcommonDao;

/**
 * 通用DAO
 * @author lordtan
 * @date 2013-1-1
 */
@Repository
public class CommonDao implements IcommonDao{
	@PersistenceUnit
	private EntityManagerFactory emf;

	@PersistenceContext
	private EntityManager em;  //don't know if it works
	
	/* (non-Javadoc)
	 * @see org.lordtan.dao.IcommonDao#findById()
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Object findById(Class claz, String id) {
		return em.find(claz, id);
	}

	/* 根据jpal查询结果
	 * @see org.lordtan.dao.IcommonDao#queryByJpql(java.lang.String, java.util.Map)
	 */
	@SuppressWarnings("rawtypes")
	@Override
	public List queryByJpql(String jpql, java.util.Map<String, Object> parameter) {
		if(StringUtils.isEmpty(jpql)){
			return null;
		}
		EntityManager em = emf.createEntityManager();
		try {
			Query query = em.createQuery(jpql);
			if(null!=parameter){
				Set<String> set = parameter.keySet();
				Iterator<String> it = set.iterator();
				while(it.hasNext()){
					String key = it.next();
					query.setParameter(key, parameter.get(key));
				}
			}
			return query.getResultList();
		}finally {
			if (em != null) {
			    em.close();
			}
		}
	}
	
	/**
	 * 批量插入Entity，成功返回1，不成功返回-1
	 * @param entites
	 * @return
	 */
	@Transactional
	public int insertEntities(List<Object> entites){
		if(null==entites){
			return -1;
		}
		EntityManager em = emf.createEntityManager();
		try {
		    for(Object entity : entites){
		    	em.persist(entity); //持久化
		    }
		}catch(Exception e){
			return -1;
		}finally {
			if (em != null) {
			    em.close();
			}
		}
		return 1;
	}
	
	
	/** 
	 * 插入单个Entity
	 * @see org.lordtan.dao.IcommonDao#insertEntity(java.lang.Object)
	 */
	@Override
	@Transactional
	public int insertEntity(Object entity) {
		if(null==entity){
			return -1;
		}
		try {
			em.persist(entity);
		}catch(Exception e){
			return -1;
		}finally {
			if (em != null) {
			    em.close();
			}
		}
		return 1;
	}

	/** 
	 * 批量更新Entity
	 * @see org.lordtan.dao.IcommonDao#updateEntites(java.util.List)
	 */
	@Override
	@Transactional
	public int updateEntites(List<Object> entites) {
		if(null==entites){
			return -1;
		}
		try {
			em.getTransaction().begin();
		    for(Object entity : entites){
		    	em.merge(entity);
		    }
			em.getTransaction().commit();
		}catch(Exception e){
			return -1;
		}finally {
			if (em != null) {
			    em.close();
			}
		}
		return 1;
	}

	/** 
	 * 更新单个Entity
	 * @see org.lordtan.dao.IcommonDao#updateEntity(java.lang.Object)
	 */
	@Override
	@Transactional
	public int updateEntity(Object entity) {
		if(null==entity){
			return -1;
		}
		try {
			em.merge(entity);
		}catch(Exception e){
			return -1;
		}finally {
			if (em != null) {
			    em.close();
			}
		}
		return 1;
	}

	/**
	 * 删除Entity，成功返回1，不成功返回-1
	 * @param entites
	 * @return
	 */
	@Transactional
	public int removeEntites(List<Object> entites){
		if(null==entites){
			return -1;
		}
		EntityManager em = emf.createEntityManager();
		try {
			em.getTransaction().begin();
		    for(Object entity : entites){
		    	em.remove(entity); //删除实体
		    }
			em.getTransaction().commit();
		}catch(Exception e){
			return -1;
		}finally {
			if (em != null) {
			    em.close();
			}
		}
		return 1;
	}

	/**
	 * 根据ids删除实体
	 * @param ids
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	@Transactional
	public int removeEntites(List<String> ids,Class claz){
	    String entityName = claz.getSimpleName(); //实体的名称
	    String idName = null ; //id字段的名称
	    Field [] fields = claz.getDeclaredFields();
	    for(Field field : fields){
			Annotation[] ans = field.getAnnotations();
			if(ans.length>0){
				Annotation an = ans[0];
				//标注为id的则是要招的Field
				if("Id".equals(an.annotationType().getSimpleName())){
					idName = field.getName();
					break;
				}
			}
		}
	    if(!StringUtils.isEmpty(idName)){
	    	String jpql = "DELETE FROM "+entityName+" e WHERE e."+idName+" IN "+
	                   JpqlUtils.buildInConditions(ids);
	    	EntityManager em = emf.createEntityManager();
	    	em.getTransaction().begin();
	    	Query query = em.createQuery(jpql);
	    	int rel = query.executeUpdate();
	    	em.getTransaction().commit();
	    	return rel;
	    }else{
	    	return -1;
	    }
	}
}
